1 using System;
2 using UnityEngine;
3
4 namespace UnityStandardAssets.ImageEffects
5 {
6 public enum LensflareStyle34
7 {
8 Ghosting = 0,
9 Anamorphic = 1,
10 Combined = 2,
11 }
12
13 public enum TweakMode34
14 {
15 Basic = 0,
16 Complex = 1,
17 }
18
19 public enum HDRBloomMode
20 {
21 Auto = 0,
22 On = 1,
23 Off = 2,
24 }
25
26 public enum BloomScreenBlendMode
27 {
28 Screen = 0,
29 Add = 1,
30 }
31
32 [ExecuteInEditMode]
33 [RequireComponent(typeof(Camera))]
34 [AddComponentMenu("Image Effects/Bloom and Glow/BloomAndFlares (3.5, Deprecated)")]
35 public class BloomAndFlares : PostEffectsBase
36 {
37 public TweakMode34 tweakMode = 0;
38 public BloomScreenBlendMode screenBlendMode = BloomScreenBlendMode.Add;
39
40 public HDRBloomMode hdr = HDRBloomMode.Auto;
41 private bool doHdr = false;
42 public float sepBlurSpread = 1.5f;
43 public float useSrcAlphaAsMask = 0.5f;
44
45 public float bloomIntensity = 1.0f;
46 public float bloomThreshold = 0.5f;
47 public int bloomBlurIterations = 2;
48
49 public bool lensflares = false;
50 public int hollywoodFlareBlurIterations = 2;
51 public LensflareStyle34 lensflareMode = (LensflareStyle34)1;
52 public float hollyStretchWidth = 3.5f;
53 public float lensflareIntensity = 1.0f;
54 public float lensflareThreshold = 0.3f;
55 public Color flareColorA = new Color(0.4f, 0.4f, 0.8f, 0.75f);
56 public Color flareColorB = new Color(0.4f, 0.8f, 0.8f, 0.75f);
57 public Color flareColorC = new Color(0.8f, 0.4f, 0.8f, 0.75f);
58 public Color flareColorD = new Color(0.8f, 0.4f, 0.0f, 0.75f);
59 public Texture2D lensFlareVignetteMask;
60
61 public Shader lensFlareShader;
62 private Material lensFlareMaterial;
63
64 public Shader vignetteShader;
65 private Material vignetteMaterial;
66
67 public Shader separableBlurShader;
68 private Material separableBlurMaterial;
69
70 public Shader addBrightStuffOneOneShader;
71 private Material addBrightStuffBlendOneOneMaterial;
72
73 public Shader screenBlendShader;
74 private Material screenBlend;
75
76 public Shader hollywoodFlaresShader;
77 private Material hollywoodFlaresMaterial;
78
79 public Shader brightPassFilterShader;
80 private Material brightPassFilterMaterial;
81
82
83 public override bool CheckResources()
84 {
85 CheckSupport(false);
86
87 screenBlend = CheckShaderAndCreateMaterial(screenBlendShader, screenBlend);
88 lensFlareMaterial = CheckShaderAndCreateMaterial(lensFlareShader, lensFlareMaterial);
89 vignetteMaterial = CheckShaderAndCreateMaterial(vignetteShader, vignetteMaterial);
90 separableBlurMaterial = CheckShaderAndCreateMaterial(separableBlurShader, separableBlurMaterial);
91 addBrightStuffBlendOneOneMaterial = CheckShaderAndCreateMaterial(addBrightStuffOneOneShader, addBrightStuffBlendOneOneMaterial);
92 hollywoodFlaresMaterial = CheckShaderAndCreateMaterial(hollywoodFlaresShader, hollywoodFlaresMaterial);
93 brightPassFilterMaterial = CheckShaderAndCreateMaterial(brightPassFilterShader, brightPassFilterMaterial);
94
95 if (!isSupported)
96 ReportAutoDisable();
97 return isSupported;
98 }
99
100 void OnRenderImage(RenderTexture source, RenderTexture destination)
101 {
102 if (CheckResources() == false)
103 {
104 Graphics.Blit(source, destination);
105 return;
106 }
107
108 // screen blend is not supported when HDR is enabled (will cap values)
109
110 doHdr = false;
111 if (hdr == HDRBloomMode.Auto)
112 doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
113 else
114 {
115 doHdr = hdr == HDRBloomMode.On;
116 }
117
118 doHdr = doHdr && supportHDRTextures;
119
120 BloomScreenBlendMode realBlendMode = screenBlendMode;
121 if (doHdr)
122 realBlendMode = BloomScreenBlendMode.Add;
123
124 var rtFormat = (doHdr) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.Default;
125 RenderTexture halfRezColor = RenderTexture.GetTemporary(source.width / 2, source.height / 2, 0, rtFormat);
126 RenderTexture quarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
127 RenderTexture secondQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
128 RenderTexture thirdQuarterRezColor = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0, rtFormat);
129
130 float widthOverHeight = (1.0f * source.width) / (1.0f * source.height);
131 float oneOverBaseSize = 1.0f / 512.0f;
132
133 // downsample
134
135 Graphics.Blit(source, halfRezColor, screenBlend, 2); // <- 2 is stable downsample
136 Graphics.Blit(halfRezColor, quarterRezColor, screenBlend, 2); // <- 2 is stable downsample
137
138 RenderTexture.ReleaseTemporary(halfRezColor);
139
140 // cut colors (thresholding)
141
142 BrightFilter(bloomThreshold, useSrcAlphaAsMask, quarterRezColor, secondQuarterRezColor);
143 quarterRezColor.DiscardContents();
144
145 // blurring
146
147 if (bloomBlurIterations < 1) bloomBlurIterations = 1;
148
149 for (int iter = 0; iter < bloomBlurIterations; iter++)
150 {
151 float spreadForPass = (1.0f + (iter * 0.5f)) * sepBlurSpread;
152 separableBlurMaterial.SetVector("offsets", new Vector4(0.0f, spreadForPass * oneOverBaseSize, 0.0f, 0.0f));
153
154 RenderTexture src = iter == 0 ? secondQuarterRezColor : quarterRezColor;
155 Graphics.Blit(src, thirdQuarterRezColor, separableBlurMaterial);
156 src.DiscardContents();
157
158 separableBlurMaterial.SetVector("offsets", new Vector4((spreadForPass / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
159 Graphics.Blit(thirdQuarterRezColor, quarterRezColor, separableBlurMaterial);
160 thirdQuarterRezColor.DiscardContents();
161 }
162
163 // lens flares: ghosting, anamorphic or a combination
164
165 if (lensflares)
166 {
167
168 if (lensflareMode == 0)
169 {
170
171 BrightFilter(lensflareThreshold, 0.0f, quarterRezColor, thirdQuarterRezColor);
172 quarterRezColor.DiscardContents();
173
174 // smooth a little, this needs to be resolution dependent
175 /*
176 separableBlurMaterial.SetVector ("offsets", Vector4 (0.0ff, (2.0ff) / (1.0ff * quarterRezColor.height), 0.0ff, 0.0ff));
177 Graphics.Blit (thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
178 separableBlurMaterial.SetVector ("offsets", Vector4 ((2.0ff) / (1.0ff * quarterRezColor.width), 0.0ff, 0.0ff, 0.0ff));
179 Graphics.Blit (secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
180 */
181 // no ugly edges!
182
183 Vignette(0.975f, thirdQuarterRezColor, secondQuarterRezColor);
184 thirdQuarterRezColor.DiscardContents();
185
186 BlendFlares(secondQuarterRezColor, quarterRezColor);
187 secondQuarterRezColor.DiscardContents();
188 }
189
190 // (b) hollywood/anamorphic flares?
191
192 else
193 {
194
195 // thirdQuarter has the brightcut unblurred colors
196 // quarterRezColor is the blurred, brightcut buffer that will end up as bloom
197
198 hollywoodFlaresMaterial.SetVector("_threshold", new Vector4(lensflareThreshold, 1.0f / (1.0f - lensflareThreshold), 0.0f, 0.0f));
199 hollywoodFlaresMaterial.SetVector("tintColor", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * flareColorA.a * lensflareIntensity);
200 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 2);
201 thirdQuarterRezColor.DiscardContents();
202
203 Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 3);
204 secondQuarterRezColor.DiscardContents();
205
206 hollywoodFlaresMaterial.SetVector("offsets", new Vector4((sepBlurSpread * 1.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
207 hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth);
208 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
209 thirdQuarterRezColor.DiscardContents();
210
211 hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 2.0f);
212 Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, hollywoodFlaresMaterial, 1);
213 secondQuarterRezColor.DiscardContents();
214
215 hollywoodFlaresMaterial.SetFloat("stretchWidth", hollyStretchWidth * 4.0f);
216 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, hollywoodFlaresMaterial, 1);
217 thirdQuarterRezColor.DiscardContents();
218
219 if (lensflareMode == (LensflareStyle34)1)
220 {
221 for (int itera = 0; itera < hollywoodFlareBlurIterations; itera++)
222 {
223 separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
224 Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
225 secondQuarterRezColor.DiscardContents();
226
227 separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
228 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
229 thirdQuarterRezColor.DiscardContents();
230 }
231
232 AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
233 secondQuarterRezColor.DiscardContents();
234 }
235 else
236 {
237
238 // (c) combined
239
240 for (int ix = 0; ix < hollywoodFlareBlurIterations; ix++)
241 {
242 separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
243 Graphics.Blit(secondQuarterRezColor, thirdQuarterRezColor, separableBlurMaterial);
244 secondQuarterRezColor.DiscardContents();
245
246 separableBlurMaterial.SetVector("offsets", new Vector4((hollyStretchWidth * 2.0f / widthOverHeight) * oneOverBaseSize, 0.0f, 0.0f, 0.0f));
247 Graphics.Blit(thirdQuarterRezColor, secondQuarterRezColor, separableBlurMaterial);
248 thirdQuarterRezColor.DiscardContents();
249 }
250
251 Vignette(1.0f, secondQuarterRezColor, thirdQuarterRezColor);
252 secondQuarterRezColor.DiscardContents();
253
254 BlendFlares(thirdQuarterRezColor, secondQuarterRezColor);
255 thirdQuarterRezColor.DiscardContents();
256
257 AddTo(1.0f, secondQuarterRezColor, quarterRezColor);
258 secondQuarterRezColor.DiscardContents();
259 }
260 }
261 }
262
263 // screen blend bloom results to color buffer
264
265 screenBlend.SetFloat("_Intensity", bloomIntensity);
266 screenBlend.SetTexture("_ColorBuffer", source);
267 Graphics.Blit(quarterRezColor, destination, screenBlend, (int)realBlendMode);
268
269 RenderTexture.ReleaseTemporary(quarterRezColor);
270 RenderTexture.ReleaseTemporary(secondQuarterRezColor);
271 RenderTexture.ReleaseTemporary(thirdQuarterRezColor);
272 }
273
274 private void AddTo(float intensity_, RenderTexture from, RenderTexture to)
275 {
276 addBrightStuffBlendOneOneMaterial.SetFloat("_Intensity", intensity_);
277 Graphics.Blit(from, to, addBrightStuffBlendOneOneMaterial);
278 }
279
280 private void BlendFlares(RenderTexture from, RenderTexture to)
281 {
282 lensFlareMaterial.SetVector("colorA", new Vector4(flareColorA.r, flareColorA.g, flareColorA.b, flareColorA.a) * lensflareIntensity);
283 lensFlareMaterial.SetVector("colorB", new Vector4(flareColorB.r, flareColorB.g, flareColorB.b, flareColorB.a) * lensflareIntensity);
284 lensFlareMaterial.SetVector("colorC", new Vector4(flareColorC.r, flareColorC.g, flareColorC.b, flareColorC.a) * lensflareIntensity);
285 lensFlareMaterial.SetVector("colorD", new Vector4(flareColorD.r, flareColorD.g, flareColorD.b, flareColorD.a) * lensflareIntensity);
286 Graphics.Blit(from, to, lensFlareMaterial);
287 }
288
289 private void BrightFilter(float thresh, float useAlphaAsMask, RenderTexture from, RenderTexture to)
290 {
291 if (doHdr)
292 brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f, 0.0f, 0.0f));
293 else
294 brightPassFilterMaterial.SetVector("threshold", new Vector4(thresh, 1.0f / (1.0f - thresh), 0.0f, 0.0f));
295 brightPassFilterMaterial.SetFloat("useSrcAlphaAsMask", useAlphaAsMask);
296 Graphics.Blit(from, to, brightPassFilterMaterial);
297 }
298
299 private void Vignette(float amount, RenderTexture from, RenderTexture to)
300 {
301 if (lensFlareVignetteMask)
302 {
303 screenBlend.SetTexture("_ColorBuffer", lensFlareVignetteMask);
304 Graphics.Blit(from, to, screenBlend, 3);
305 }
306 else
307 {
308 vignetteMaterial.SetFloat("vignetteIntensity", amount);
309 Graphics.Blit(from, to, vignetteMaterial);
310 }
311 }
312
313 }
314 }